﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Text;
using System.Configuration;

using BizElements.BusinessLayer;

namespace BizElements.Web
{
    /// <summary>
    /// <see cref="DataGrid"/> template which displays and edits the value of a bound field in a <see cref="BoundCalendar"/> control.
    /// </summary>
    public class BoundCalendarTemplate : BoundTemplateBase
    {
        #region Constructors.

        /// <summary>
        /// Initializes a new instance of the <see cref="BoundCalendarTemplate"/> class.
        /// </summary>
        public BoundCalendarTemplate()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="BoundCalendarTemplate"/> class.
        /// </summary>
        /// <param name="field"><see cref="IBindableField"/> that contains a reference and meta-data for a bound business class property.</param>
        /// <param name="formatter">The <see cref="IMessageFormatter"/> object used to format bound values.</param>
        public BoundCalendarTemplate(IBindableField field, IMessageFormatter formatter)
            : base(field, formatter)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="BoundCalendarTemplate"/> class.
        /// </summary>
        /// <param name="field"><see cref="IBindableField"/> that contains a reference and meta-data for a bound business class property.</param>
        /// <param name="formatter">The <see cref="IMessageFormatter"/> object used to format bound values.</param>
        /// <param name="skinID">The skin to apply to the controls generated by this template.</param>
        public BoundCalendarTemplate(IBindableField field, IMessageFormatter formatter, string skinID)
            : base(field, formatter, skinID)
        {
        }

        #endregion

        #region Methods.

        /// <summary>
        /// Defines the <see cref="DataGrid"/> that child calendar controls and the template belong to.
        /// </summary>
        /// <param name="container">The <b>TableCell</b> which contains the controls instantiated by this template.</param>
        public override void InstantiateIn(Control container)
        {
            Control ctl;
            if (this.AccessMode != FieldAccessMode.ReadOnly)
            {
                ctl = CreateCalendar(false);
                ctl.DataBinding += new EventHandler(this.BindDisplayValueToCalendar);
            }
            else
            {
                ctl = CreateLabel();
                ctl.DataBinding += new EventHandler(this.BindDisplayValueToLabel);
            }

            container.Controls.Add(ctl);
        }

        private BoundCalendar CreateCalendar(bool forceApplySkin)
        {
            BoundCalendar calendar = new BoundCalendar();
            if (this.SkinID != null)
                calendar.SkinID = this.SkinID;

            if (forceApplySkin || this.SkinID != null)
            {
                Page page = HttpContext.Current.Handler as Page;
                if (page != null)
                    calendar.ApplyStyleSheetSkin(page);
            }

            return calendar;
        }

        private Label CreateLabel()
        {
            BoundCalendar calendar = CreateCalendar(true);
            Label lbl = new Label();
            lbl.CopyBaseAttributes(calendar);
            lbl.CssClass = (calendar.ReadOnlyCssClass != "") ? calendar.ReadOnlyCssClass : calendar.CssClass;
            lbl.BackColor = calendar.BackColor;
            return lbl;
        }

        private void BindDisplayValueToCalendar(object sender, EventArgs e)
        {
            BoundCalendar calendar = (BoundCalendar)sender;
            ApplyStyle(calendar);

            DataGridItem currentItem = (DataGridItem)calendar.NamingContainer;
            object value = DataBinder.Eval(currentItem.DataItem, this.BoundField.BindingName);
            calendar.SelectedValue = (value != null) ? (DateTime?)Convert.ToDateTime(value) : null;

            bool isReadOnly = ConfigureAccessMode(calendar);
            if (isReadOnly)
            {
                calendar.BackColor = Color.Transparent;
                calendar.Style["cursor"] = "pointer";
            }
        }

        private void BindDisplayValueToLabel(object sender, EventArgs e)
        {
            Label lbl = (Label)sender;
            ApplyStyle(lbl);
            DataGridItem currentItem = (DataGridItem)lbl.NamingContainer;
            object value = DataBinder.Eval(currentItem.DataItem, this.BoundField.BindingName);
            lbl.Text = (this.Formatter != null) ? this.Formatter.Format(value) : Convert.ToString(value);
            lbl.BackColor = Color.Transparent;
        }

        #endregion
    }
}